﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;

using Microsoft.Win32;


using NHibernate;
using NHibernate.Cfg;
using NHibernateConfig = NHibernate.Cfg.Configuration;
using System.Web;
using System.Configuration;

namespace PlainOldVersionControl.Data
{
    internal class PlainSessionFactory
    {
        internal static string DatabaseServer
        {
            get
            {
                string dbserver = Settings.CurrentDatabase;                

                if (string.IsNullOrEmpty(dbserver))
                {
                    throw new InvalidOperationException("database server not found");
                }
                return dbserver;
            }
        }

        private static ISessionFactory _sessionFactory;
        private static ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    BuildFactory();
                }
                return _sessionFactory;
            }
        }


        private static IDictionary<int, ISession> sessions = new Dictionary<int, ISession>();

        internal static ISession Session
        {
            get
            {
                ISession session = null;
                if (!sessions.ContainsKey(Thread.CurrentThread.ManagedThreadId))
                {
                    session = SessionFactory.OpenSession();
                    sessions.Add(Thread.CurrentThread.ManagedThreadId, session);
                }
                else
                {
                    session = sessions[Thread.CurrentThread.ManagedThreadId];
                }
                if (!session.IsOpen)
                {
                    session = SessionFactory.OpenSession();
                    sessions[Thread.CurrentThread.ManagedThreadId] = session;

                }
                return session;
            }
        }

        internal static void BeginTransaction()
        {
            Session.BeginTransaction();
        }

        internal static void BuildFactory()
        {
            Settings.EnsureInit();

            if (_sessionFactory == null)
            {
                string connstr = @"Data Source={0};";
                var configuration = new NHibernateConfig();
                configuration.SetProperty("dialect", "NHibernate.Dialect.SQLiteDialect");
                configuration.SetProperty("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
                configuration.SetProperty("connection.connection_string", string.Format(connstr, DatabaseServer));
                configuration.SetProperty("connection.driver_class", "NHibernate.Driver.SQLite20Driver");
                configuration.SetProperty("proxyfactory.factory_class", "NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu");
                configuration.AddAssembly("PlainOldVersionControl");
                _sessionFactory = configuration.BuildSessionFactory();
            }
        }
    }
}
